﻿using Casamiel.Domain;
using Casamiel.Domain.Entity;

using Smooth.IoC.UnitOfWork.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Dapper;

namespace Casamiel.Infrastructure.Repositories
{
    /// <summary>
    /// 
    /// </summary>
    public sealed class WxOpenIdRepository : BaseRepository<WxOpenId, string>, IWxOpenIdRepository
    {
        public WxOpenIdRepository(IDbFactory factory) : base(factory)
        {
        }

        public async Task<WxOpenId> GetByIdAsync<TSession>(int id) where TSession : class, ISession
        {
            using (var session = Factory.Create<TSession>())
            {
                return await session.QuerySingleOrDefaultAsync<WxOpenId>($"SELECT top 1 * FROM {Sql.Table<WxOpenId>(session.SqlDialect)} where id=@id", new { id })
                     .ConfigureAwait(false);
            }
        }

        /// <summary>
        /// Gets the by openid appid async.
        /// </summary>
        /// <returns>The by openid appid async.</returns>
        /// <param name="openid">Openid.</param>
        /// <param name="appId">App identifier.</param>
        /// <typeparam name="TSession">The 1st type parameter.</typeparam>
        public async Task<WxOpenId> GetByOpenidAppidAsync<TSession>(string openid, string appId) where TSession : class, ISession
        {
            using (var session = Factory.Create<TSession>())
            {
                return await session.QuerySingleOrDefaultAsync<WxOpenId>($"SELECT top 1 * FROM {Sql.Table<WxOpenId>(session.SqlDialect)} where openid=@openid and appId=@appId", new { openid, appId })
                     .ConfigureAwait(false);
            }
        }

        /// <summary>
        /// Updates the by moible async.
        /// </summary>
        /// <returns>The by moible async.</returns>
        /// <param name="mobile">Mobile.</param>
        /// <typeparam name="TSession">The 1st type parameter.</typeparam>
        public async Task UpdateByMoibleAsync<TSession>(string mobile) where TSession : class, ISession
        {
            using (var session = Factory.Create<TSession>())
            {
                await session.ExecuteAsync($"Update {Sql.Table<WxOpenId>(session.SqlDialect)} set mobile='' where mobile=@mobile".CheckSafeSql(), new { mobile }).ConfigureAwait(false);
            }
        }

		/// <summary>
		/// 
		/// </summary>
		/// <typeparam name="TSession"></typeparam>
		/// <param name="entity"></param>
		/// <returns></returns>
		public new async Task<bool> UpdateAsync<TSession>(WxOpenId entity) where TSession : class, ISession
		{

			using (var session = Factory.Create<TSession>()) {

				var sql = $"update {Sql.Table<WxOpenId>(session.SqlDialect)} set [unionid]=@UnionId,[session_key]=@Session_key,nickname=@NickName,Gender=@Gender, [mobile]=@Mobile, [update_time] =@Update_time where [openid]=@OpenId";
				return await session.ExecuteAsync(sql.CheckSafeSql(),entity).ConfigureAwait(false)>0;
			}
		}

		public async Task<WxOpenId> GetByUnionIdAsync<TSession>(string unionId) where TSession : class, ISession
        {
            using (var session = Factory.Create<TSession>())
            {
                return await session.Connection.QueryFirstOrDefaultAsync<WxOpenId>($"SELECT  top 1 * FROM {Sql.Table<WxOpenId>(session.SqlDialect)} where unionId=@unionId and mobile<>''", new { unionId })
                    .ConfigureAwait(false);
            }

        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TSession"></typeparam>
        /// <param name="appId"></param>
        /// <param name="mobile"></param>
        /// <returns></returns>
        public async Task<WxOpenId>GetByAppIdMobileAsync<TSession>(string appId, string mobile)where TSession : class, ISession
        {

            string sql = " select top 1 * from wx_openid where mobile =@mobile and appId=@appId";
            using (var session = Factory.Create<TSession>()) {
                WxOpenId entity= await session.Connection.QueryFirstOrDefaultAsync<WxOpenId>(sql, new { appId, mobile }).ConfigureAwait(false);
				if (entity != null) {
                    return entity;
				}
            }

            sql = "select unionid from wx_openid where mobile =@mobile";
            using (var session = Factory.Create<TSession>()) {
                WxOpenId entity = await session.Connection.QueryFirstOrDefaultAsync<WxOpenId>(sql, new {  mobile }).ConfigureAwait(false);
                if (entity != null && entity.UnionId is {Length:>0 }) {
                    sql = "select top 1 * from wx_openid where unionId=@UnionId and appId=@appId";
                     return await session.Connection.QueryFirstOrDefaultAsync<WxOpenId>(sql, new { appId, entity.UnionId }).ConfigureAwait(false);
              }
            }
            return null;
        }
        /// <summary>
        /// Gets the by moible async.
        /// </summary>
        /// <returns>The by moible async.</returns>
        /// <param name="mobile">mobile identifier.</param>
        /// <typeparam name="TSession">The 1st type parameter.</typeparam>
        public async Task<WxOpenId> GetByMoibleAsync<TSession>(string mobile) where TSession : class, ISession
        {
            using (var session = Factory.Create<TSession>())
            {
                return await session.QueryFirstOrDefaultAsync<WxOpenId>($"SELECT  top 1 * FROM {Sql.Table<WxOpenId>(session.SqlDialect)} where mobile=@mobile", new { mobile }).ConfigureAwait(false);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns>The by union identifier app identifier async.</returns>
        /// <param name="unionId">Union identifier.</param>
        /// <param name="appId">App identifier.</param>
        /// <typeparam name="TSession">The 1st type parameter.</typeparam>
        public async Task<WxOpenId> GetByUnionIdAppIdAsync<TSession>(string unionId, string appId) where TSession : class, ISession
        {
            using (var session = Factory.Create<TSession>())
            {
                return await session.QueryFirstOrDefaultAsync<WxOpenId>($"SELECT  top 1 * FROM {Sql.Table<WxOpenId>(session.SqlDialect)} where unionId=@unionId and appId=@appId", new { unionId,appId })
                      .ConfigureAwait(false);
            }
        }
    }
}
